package org.duoduo.common.redis.jedis3_1_0;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.*;

import java.util.HashSet;
import java.util.Set;

public class RedisPool {

    protected final Logger log = LoggerFactory.getLogger(getClass().getName());

    protected String redisClusterType;

    protected GenericObjectPoolConfig<?> poolConfig;

    protected int timeout = Protocol.DEFAULT_TIMEOUT;

    protected int soTimeout = Protocol.DEFAULT_TIMEOUT;

    protected int maxAttempts = 5;

    protected String password;

    private Integer databases;

    private String masterName;

    private JedisCluster jedisCluster;

    private JedisSentinelPool jedisSentinelPool = null;

    private JedisPool jedisPool = null;

    public RedisPool(String redisClusterType, Set<String> clusters, final GenericObjectPoolConfig<?> poolConfig, int databases, String masterName, int timeout, int soTimeout, int maxAttempts, final String password) {
    	this.redisClusterType = redisClusterType;
        this.poolConfig = poolConfig;
        this.timeout = timeout;
        this.soTimeout = soTimeout;
        this.maxAttempts = maxAttempts;
        this.password = password;
        this.databases = databases;
        this.masterName = masterName;
        this.redisClusterType = redisClusterType;

        initPool(clusters);
    }

    private void initPool(Set<String> clusters) {
    	if(redisClusterType.equals("cluster")){
    		initCluster(clusters);
    	}else if(redisClusterType.equals("single")){
    		initJedisPool(clusters);
    	}else{
    		initSentinel(clusters);
    	}
    }

    private void initJedisPool(Set<String> nodes){
    	for (String ipPort : nodes) {
	    	String[] ipPortPair = ipPort.split(":");
	    	jedisPool = new JedisPool(poolConfig, ipPortPair[0].trim(), Integer.valueOf(ipPortPair[1].trim()));
	    	return;
    	}
    }

    private void initCluster(Set<String> clusters){
    	 Set<HostAndPort> nodes = new HashSet<HostAndPort>();
         for (String ipPort : clusters) {
             String[] ipPortPair = ipPort.split(":");
             nodes.add(new HostAndPort(ipPortPair[0].trim(), Integer.valueOf(ipPortPair[1].trim())));
         }
         if(password == null)
         	jedisCluster = new JedisCluster(nodes, timeout, soTimeout, maxAttempts, poolConfig);
         else
         	jedisCluster = new JedisCluster(nodes, timeout, soTimeout, maxAttempts, password, poolConfig);
    }

    private void initSentinel(Set<String> clusters){
    	jedisSentinelPool = new JedisSentinelPool(masterName, clusters, poolConfig, timeout, soTimeout, password, databases);
    }

	public Object getResource() {
		if(redisClusterType.equals("cluster")){
			return jedisCluster;
		}else if(redisClusterType.equals("single")){
			return jedisPool.getResource();
		}else{
			return jedisSentinelPool.getResource();
		}
	}

	public void returnResource(Object jedis) {
		if(!redisClusterType.equals("cluster") && jedis instanceof Jedis && jedis != null){
			((Jedis)jedis).close();
		}
	}

	public String getRedisClusterType() {
		return redisClusterType;
	}

}
